﻿using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System;

namespace Rabbit.Controls
{
    
    public class TextBlockEx : TextBlock
    {
        //private static readonly Regex RE_URL = new Regex(@"#\w+#|@\w+|http://\w*\.(\w+\.\w+|\w+)\S+", RegexOptions.IgnoreCase);
        private static readonly Regex RE_URL = new Regex(@"#\w+#|@\w+|https?://[\d\-a-zA-Z]+(\.[\d\-a-zA-Z]+)+[/a-zA-Z0-9\.]+", RegexOptions.IgnoreCase);
        public new static readonly DependencyProperty TextProperty =
            DependencyProperty.RegisterAttached("Text", typeof(string), typeof(TextBlockEx),
            new PropertyMetadata(null, OnTextChanged));


        public static RoutedEvent OnUserNameClickedEvent = EventManager.RegisterRoutedEvent(
            "OnUserNameClicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TextBlockEx));
        public event RoutedEventHandler OnUserNameClicked
        {
            add { AddHandler(OnUserNameClickedEvent, value); }
            remove { RemoveHandler(OnUserNameClickedEvent, value); }
        }

        public static RoutedEvent OnUrlClickedEvent = EventManager.RegisterRoutedEvent(
           "OnUrlClicked", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(TextBlockEx));
        public event RoutedEventHandler OnUrlClicked
        {
            add { AddHandler(OnUrlClickedEvent, value); }
            remove { RemoveHandler(OnUrlClickedEvent, value); }
        }

        public static RoutedEvent OnTopicClickedEvent = EventManager.RegisterRoutedEvent(
          "OnTopicClicked", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(TextBlockEx));
        public event RoutedEventHandler OnTopicClicked
        {
            add { AddHandler(OnTopicClickedEvent, value); }
            remove { RemoveHandler(OnTopicClickedEvent, value); }
        }

        public static Action<string> OnUserClickedDelegate;

        public static string GetText(DependencyObject d) { return d.GetValue(TextProperty) as string; }
        public static void SetText(DependencyObject d, string value) { d.SetValue(TextProperty, value); }
        private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TextBlockEx txtBlock = d as TextBlockEx;
            if (txtBlock == null)
                return;
            txtBlock.ModifyText(e.NewValue.ToString());
        }

        public void ModifyText(string newText)
        {
            //clear it's content first
            this.Inlines.Clear();

            //read its new value
            if (string.IsNullOrEmpty(newText))
            {
                return;
            }

            // Find all URLs using a regular expression            
            int last_pos = 0;
            foreach (Match match in RE_URL.Matches(newText))
            {
                // Copy raw string from the last position up to the match          
                if (match.Index != last_pos)
                {
                    var raw_text = newText.Substring(last_pos, match.Index - last_pos);
                    this.Inlines.Add(new Run(raw_text));
                }

                string url = match.Value;
                Hyperlink link;

                if (url.StartsWith("@"))//user name
                {
                    string Parameter = url.Substring(1, url.Length - 1);
                    link = new Hyperlink(new Run(match.Value))
                    {
                        CommandParameter = Parameter
                    };
                    link.Click += (sender, args) =>
                    {
                        RaiseEvent(new RoutedEventArgs(OnUserNameClickedEvent) { Source = link });
                    };
                }
                else
                {
                    if (url.StartsWith("#"))
                    {
                        url = "http://t.sohu.com/ht/" + HttpUtility.UrlEncode(url.Substring(1, url.Length - 2), Encoding.GetEncoding("GB2312"));
                    }
                    link = new Hyperlink(new Run(match.Value))
                    {
                        CommandParameter = url
                    };
                    link.Click += OnUrlClick;
                }
                 
                this.Inlines.Add(link);

                // Update the last matched position         
                last_pos = match.Index + match.Length;
            }

            // Finally, copy the remainder of the string           
            if (last_pos < newText.Length)
                this.Inlines.Add(new Run(newText.Substring(last_pos)));
        }
        private static void OnUrlClick(object sender, RoutedEventArgs e)
        {
            var link = (Hyperlink)sender;
            Process.Start(link.CommandParameter.ToString());
        }
    }
}
